﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Text.RegularExpressions;

namespace Dycox.Validation
{
    [Serializable]
    public abstract class Validator
    {
        protected Validator()
        {

        }

        protected Validator(SerializationInfo info, StreamingContext context)
            : this()
        {

        }

        public event ValidationEventHandler Validating;

        internal protected abstract ValidationResult IsValid(object value, PropertyValidationContext context);

        public virtual ValidationResult IsValid(object value)
        {
            OnValidating(new ValidationEventArgs(value));
            return IsValid(value, null);
        }

        protected virtual void OnValidating(ValidationEventArgs e)
        {
            if (Validating != null)
                Validating(this, e);
        }

        public void Validate(object value)
        {
            if (IsValid(value) == ValidationResult.Invalid)
                throw new ValidationException(ErrorMessage);
        }

        string _errorMessage;
        [DefaultValue((string)null)]
        public virtual string ErrorMessage
        {
            get
            {
                return _errorMessage;
            }
            set
            {
                _errorMessage = value;
            }
        }

        protected virtual string DefaultErrorMessage
        {
            get
            {
                string id = "default_errmsg_" + this.GetType().Name.ToLower();
                return SR.GetString(id);
            }
        }

        internal string GetErrorMessage(PropertyValidationContext context)
        {
            string template;

            if (string.IsNullOrEmpty(_errorMessage))
                template = DefaultErrorMessage;
            else
                template = _errorMessage;

            if (context != null && context.Instance != null)
                template = Dycox.Utils.DataBinderUtil.EvalTemplate(template, context.Instance);

            return template;
        }

        //protected abstract void GetObjectData(SerializationInfo info, StreamingContext context);

        //void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        //{
        //    this.GetObjectData(info, context);
        //}

        //protected virtual void OnSerializing(StreamingContext context)
        //{
        //}

        //protected virtual void OnSerialized(StreamingContext context)
        //{
        //}

        //protected virtual void OnDeserializing(StreamingContext context)
        //{
        //}

        //protected virtual void OnDeserialized(StreamingContext context)
        //{
        //}

        //[OnSerializing]
        //private void SerializingProxy(StreamingContext context)
        //{
        //    this.OnSerializing(context);
        //}

        //[OnSerialized]
        //private void SerializedProxy(StreamingContext context)
        //{
        //    this.OnSerialized(context);
        //}

        //[OnDeserializing]
        //private void DeserializingProxy(StreamingContext context)
        //{
        //    this.OnDeserializing(context);
        //}

        //[OnDeserialized]
        //private void DeserializedProxy(StreamingContext context)
        //{
        //    this.OnDeserialized(context);
        //}
    }

}
